use std::fs::File;
use std::{io, mem};
use std::io::{BufReader, Read};
use std::default::Default;
use crate::Picture;

#[allow(dead_code)]
#[repr(packed)]
#[derive(Default)]
struct TGAHeader {
    id_size: u8,
    color_map_type: u8,
    image_type: u8,
    palette_start: u16,
    palette_size: u16,
    palette_entry_depth: u8,
    x: u16,
    y: u16,
    width: u16,
    height: u16,
    color_depth: u8,
    descriptor: u8,
}

impl Default for Picture {
    fn default() -> Self {
        Self {
            width: 0,
            height: 0,
            color_depth: 0,
            pixels: vec![]
        }
    }
}

impl Picture {
    pub fn from_tga(file_name: &str) -> io::Result<Self> {
        let file = File::open(file_name)?;
        let mut br = BufReader::new(file);
        let header: TGAHeader = unsafe {
            let mut header = [0u8; mem::size_of::<TGAHeader>()];
            br.read(&mut header).unwrap();
            mem::transmute(header)
        };

        let width = header.width;
        let height = header.height;
        println!("width: {}, height: {}, colorDepth: {}", width, height, header.color_depth);

        let bytes_to_read = width as usize * height as usize * header.color_depth as usize / 8;
        let mut pixels = vec![0; bytes_to_read as usize];
        br.read(&mut pixels).unwrap();

        Ok(Self {
            width: header.width,
            height: header.height,
            color_depth: header.color_depth,
            pixels
        })
    }

    pub fn get_pixel(&self, x: u16, y: u16) -> (u8, u8, u8, u8) {
        (
            self.pixels[(x * 4 +     y * self.width * 4) as usize],
            self.pixels[(x * 4 + 1 + y * self.width * 4) as usize],
            self.pixels[(x * 4 + 2 + y * self.width * 4) as usize],
            self.pixels[(x * 4 + 3 + y * self.width * 4) as usize],
        )
    }

    pub fn dimensions(&self) -> (u16, u16) {
        (self.width, self.height)
    }

    pub fn pixels(&self) -> &[u8] {
        &self.pixels
    }
}